<script src="../../dist/vue.global.js"></script>
<link
  rel="stylesheet"
  href="../../../../node_modules/todomvc-app-css/index.css"
/>

<div id="app">
  <section class="todoapp">
    <header class="header">
      <h1>todos</h1>
      <input
        class="new-todo"
        autofocus
        autocomplete="off"
        placeholder="What needs to be done?"
        v-model="newTodo"
        @keyup.enter="addTodo"
      />
    </header>
    <section class="main" v-show="todos.length">
      <input
        id="toggle-all"
        class="toggle-all"
        type="checkbox"
        v-model="allDone"
      />
      <label for="toggle-all">Mark all as complete</label>
      <ul class="todo-list">
        <li
          v-for="todo in filteredTodos"
          class="todo"
          :key="todo.id"
          :class="{ completed: todo.completed, editing: todo === editedTodo }"
        >
          <div class="view">
            <input class="toggle" type="checkbox" v-model="todo.completed" />
            <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
            <button class="destroy" @click="removeTodo(todo)"></button>
          </div>
          <input
            class="edit"
            type="text"
            v-model="todo.title"
            v-todo-focus="todo === editedTodo"
            @blur="doneEdit(todo)"
            @keyup.enter="doneEdit(todo)"
            @keyup.escape="cancelEdit(todo)"
          />
        </li>
      </ul>
    </section>
    <footer class="footer" v-show="todos.length">
      <span class="todo-count">
        <strong>{{ remaining }}</strong>
        <span>{{ pluralize(remaining) }} left</span>
      </span>
      <ul class="filters">
        <li>
          <a href="#/all" :class="{ selected: visibility === 'all' }">All</a>
        </li>
        <li>
          <a href="#/active" :class="{ selected: visibility === 'active' }"
            >Active</a
          >
        </li>
        <li>
          <a
            href="#/completed"
            :class="{ selected: visibility === 'completed' }"
            >Completed</a
          >
        </li>
      </ul>
      <button
        class="clear-completed"
        @click="removeCompleted"
        v-show="todos.length > remaining"
      >
        Clear completed
      </button>
    </footer>
  </section>
</div>

<script>
  const STORAGE_KEY = 'todos-vuejs-3.x'
  const todoStorage = {
    fetch() {
      const todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
      todos.forEach((todo, index) => {
        todo.id = index
      })
      todoStorage.uid = todos.length
      return todos
    },
    save(todos) {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
    },
  }

  const filters = {
    all(todos) {
      return todos
    },
    active(todos) {
      return todos.filter(todo => {
        return !todo.completed
      })
    },
    completed(todos) {
      return todos.filter(function (todo) {
        return todo.completed
      })
    },
  }

  Vue.createApp({
    // app initial state
    data: () => ({
      todos: todoStorage.fetch(),
      newTodo: '',
      editedTodo: null,
      visibility: 'all',
    }),

    // watch todos change for localStorage persistence
    watch: {
      todos: {
        handler(todos) {
          todoStorage.save(todos)
        },
        deep: true,
      },
    },

    mounted() {
      window.addEventListener('hashchange', this.onHashChange)
      this.onHashChange()
    },

    computed: {
      filteredTodos() {
        return filters[this.visibility](this.todos)
      },
      remaining() {
        return filters.active(this.todos).length
      },
      allDone: {
        get() {
          return this.remaining === 0
        },
        set(value) {
          this.todos.forEach(function (todo) {
            todo.completed = value
          })
        },
      },
    },

    // methods that implement data logic.
    // note there's no DOM manipulation here at all.
    methods: {
      addTodo() {
        var value = this.newTodo && this.newTodo.trim()
        if (!value) {
          return
        }
        this.todos.push({
          id: todoStorage.uid++,
          title: value,
          completed: false,
        })
        this.newTodo = ''
      },

      removeTodo(todo) {
        this.todos.splice(this.todos.indexOf(todo), 1)
      },

      editTodo(todo) {
        this.beforeEditCache = todo.title
        this.editedTodo = todo
      },

      doneEdit(todo) {
        if (!this.editedTodo) {
          return
        }
        this.editedTodo = null
        todo.title = todo.title.trim()
        if (!todo.title) {
          this.removeTodo(todo)
        }
      },

      cancelEdit(todo) {
        this.editedTodo = null
        todo.title = this.beforeEditCache
      },

      removeCompleted() {
        this.todos = filters.active(this.todos)
      },

      onHashChange() {
        var visibility = window.location.hash.replace(/#\/?/, '')
        if (filters[visibility]) {
          this.visibility = visibility
        } else {
          window.location.hash = ''
          this.visibility = 'all'
        }
      },

      pluralize(n) {
        return n === 1 ? 'item' : 'items'
      },
    },

    directives: {
      'todo-focus'(el, binding) {
        if (binding.value) {
          el.focus()
        }
      },
    },
  }).mount('#app')
</script>
